package com.cnt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cnt.dao.*;
import com.cnt.entity.*;
import com.cnt.service.DonationsService;
import com.cnt.util.FileUtil;
import com.cnt.vo.AchievementVo;
import com.cnt.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DonationsServiceImpl implements DonationsService {
    @Autowired
    private DonationsDao donationsDao;
    @Autowired
    private DonationRequestDao donationRequestDao;
    @Autowired
    private PersonDao personDao;
    @Autowired
    private DonationsInfoDao donationsInfoDao;
    @Autowired
    private PointsRulesDao pointsRulesDao;
    @Autowired
    private FileUtil fileUtil;

    private static String IMAGE_DIR = "src/main/resources/static/image/donationImg";

    @Override
    public ResultVo<Donations> updateDonation(Donations donations) {
        System.out.println(donations);
        Integer status = donations.getStatus();
        if (status != 1)return new ResultVo<>(2, "修改失败，提交后不能进行修改", null);
        System.out.println(donations.getDeadline()+"-------");
        int i = donationsDao.updateById(donations);
        if (i != 1) {
            return new ResultVo<>(1, "修改失败，请刷新后重试", null);
        }
        return new ResultVo<>(0, "修改成功", donations);
    }

    @Override
    public ResultVo<String> deleteDonationById(Integer id) {
        Donations donations = donationsDao.selectById(id);
        if (donations.getStatus() >= 2) {
            return new ResultVo<>(2, "没有权限，删除失败。", null);
        }
        LambdaUpdateWrapper<Donations> luw = Wrappers.lambdaUpdate();
        luw.set(Donations::getStatus, 2);
        int i = donationsDao.update(donations, luw);
        if (i != 1) {
            return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        }
        return new ResultVo<>(0, "删除成功", null);
    }

    @Override
    public ResultVo<Donations> submitDonation(Donations donations) {
        LambdaUpdateWrapper<Donations> luw = Wrappers.lambdaUpdate();
        Integer donationId = donations.getDonationId();
        luw.eq(Donations::getDonationId, donationId)
                .lt(Donations::getStatus, 2)
                .set(Donations::getStatus, 3);
        int i = donationsDao.update(null, luw);
        if (i != 1) {
            return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        }

        Donations donationsList = donationsDao.selectById(donationId);
        int pointsSum = 0;
        Integer pointsId = donationsList.getPointsId();
        String isPointsRules = donationsList.getIsPointsRules();
        for (String s : isPointsRules.split(",")) {
            int pointsRulesId = Integer.parseInt(s);
            PointsRules pointsRules = pointsRulesDao.selectById(pointsRulesId);
            Integer pointsValue = pointsRules.getPointsValue();
            pointsSum += pointsValue;
        }
        DonationRequest donationRequest = new DonationRequest();
        donationRequest.setDonationId(donationId);
        donationRequest.setTime(new Date());
        donationRequest.setIsPointsRules(isPointsRules);
        donationRequest.setPointsId(pointsId);
        donationRequest.setPointsSum(pointsSum);
        int i1 = donationRequestDao.insert(donationRequest);
        if (i1 != 1) {
            return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        }
        return new ResultVo<>(0, "提交成功", donationsDao.selectById(donations.getDonationId()));
    }


    @Override
    public ResultVo<Donations> revokeDonation(int donationId) {
        LambdaUpdateWrapper<Donations> luw = Wrappers.lambdaUpdate();
        luw.eq(Donations::getDonationId, donationId)
                .lt(Donations::getStatus, 4)
                .ne(Donations::getStatus, 2)
                .set(Donations::getStatus, 1);
        int i = donationsDao.update(null, luw);
        if (i != 1) {
            return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        }
        LambdaQueryWrapper<DonationRequest> lqw = new LambdaQueryWrapper<>();
        lqw.eq(DonationRequest::getDonationId, donationId)
                .and(wrapper -> wrapper.eq(DonationRequest::getReply, "").or().isNull(DonationRequest::getReply));
        int i1 = donationRequestDao.delete(lqw);
        if (i1 != 1) {
            return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        }
        return new ResultVo<>(0, "撤回成功", donationsDao.selectById(donationId));
    }

    @Override
    public ResultVo<List<Donations>> queryDonations(Integer minAge, Integer oleAge, String name) {
        LambdaQueryWrapper<Donations> queryWrapper = Wrappers.lambdaQuery();

        if (minAge != null && oleAge != null) {
            queryWrapper.between(Donations::getAge, minAge, oleAge);
        }

        if (StringUtils.isNotBlank(name)) {
            queryWrapper.and(i -> i.like(Donations::getAlias, name)
                    .or()
                    .like(Donations::getDonationReason, name));
        }
        queryWrapper.eq(Donations::getStatus, 5);
        List<Donations> donations = donationsDao.selectList(queryWrapper);
        return new ResultVo<List<Donations>>(0, "查询成功", donations);
    }
    @Override
    public ResultVo<List<Donations>> List(Double min, Double max, String name) {
        LambdaQueryWrapper<Donations> queryWrapper = Wrappers.lambdaQuery();

        if (max != null && min != null) {
            queryWrapper.between(Donations::getDonationAmount, min, max);
        }

        if (StringUtils.isNotBlank(name)) {
            queryWrapper.and(i -> i.like(Donations::getAlias, name)
                    .or()
                    .like(Donations::getDonationReason, name));
        }
        queryWrapper.ge(Donations::getStatus, 5);
        List<Donations> donations = donationsDao.selectList(queryWrapper);
        return new ResultVo<List<Donations>>(0, "查询成功", donations);
    }
    //求助人募捐单查找
    @Override
    public ResultVo<List<Donations>> queryDonationByPersonId(Integer personId) {
        Persons persons = personDao.selectById(personId);
        if (persons == null) {
            return new ResultVo<>(1, "找不到该用户", null);
        }
        List<Donations> donations = donationsDao.selectList(new LambdaQueryWrapper<Donations>()
                .eq(Donations::getPersonId, personId));

        return new ResultVo<>(0, "查询成功", donations);
    }

    //创建募捐单
    @Override
    @Transactional(rollbackFor = Exception.class)//添加为事务
    public ResultVo<Donations> insert(Donations donations) {
        donations.setPointsId(1);
        if (donations.getPersonId() == null)
            return new ResultVo<>(1, "创建失败，获取不到求助人", null);
        int insert = donationsDao.insert(donations);
        Donations donationsById = donationsDao.getByDonationId(donations.getDonationId());

        DonationsInfo donationsInfo = new DonationsInfo();
        donationsInfo.setDonationsInfoId(0);

        donationsInfo.setDonationId(donationsById.getDonationId());
        int insert1 = donationsInfoDao.insert(donationsInfo);
        if (insert == 0 || insert1 == 0) {
            // 手动回滚事务
            throw new RuntimeException("创建失败");
        }
        return new ResultVo<>(0, "创建成功", donationsById);
    }

    //查找募捐单
    @Override
    public ResultVo<Donations> getByDonationId(Integer donationsId) {
        Donations donation = donationsDao.getByDonationId(donationsId);
        if (donation == null) {
            return new ResultVo<>(1, "找不到该募捐单", null);
        }
        return new ResultVo<>(0, "查询成功", donation);
    }

    //上传图片
    @Override
    public ResultVo<String> uploadDonationImage(Integer donationId, MultipartFile file) {
        // 校验上传的文件大小
        long size = file.getSize();
        if (size > 16 * 1024 * 1024) { // 限制文件大小为16MB
            return new ResultVo<>(2, "图片大小不能超过16MB", null);
        }
        Donations donations = donationsDao.getByDonationId(donationId);
        // 生成文件名
        String filename = "donation_"+donationId+"_Img.jpg";

        // 保存文件到服务器 若文件名一样覆盖式写入
        Path targetPath = Paths.get(IMAGE_DIR, filename);
        try {
            Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }
        donations.setDonationImage("localhost:8888/image/donationImg/"+filename);
        int i = donationsDao.updateById(donations);
        if (i != 1) return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        try {
            Runtime.getRuntime().exec("mvn.cmd clean package");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResultVo<>(0, "图片更新成功", null);
    }

    @Override
    public ResultVo<List<String>> getTenDonation() {
        List<String> list = new ArrayList<>();
        List<Donations> indexTen = donationsDao.getIndexTen();
        for (Donations donations : indexTen) {
            String alias = donations.getAlias();
            String donationReason = donations.getDonationReason();
            double donationAmount = donations.getDonationAmount();
            list.add(alias + "因" + donationReason + "募捐了" + donationAmount + "元");
        }
        return new ResultVo<>(0, "查询成功", list);
    }

    @Override
    public ResultVo<AchievementVo> achievement() {
        /*
            1.募捐金额，2.救助人员，3.救济基金筹集金额，4.救济基金救助人数
            （3和4暂时没有，后端传0，前端自己想个数字先写死）
         */
        List<Donations> donationsList = donationsDao.selectList(null);
        double sum = 0;
        for (Donations donations : donationsList) {
            double donatedAmount = donations.getDonatedAmount();
            sum += donatedAmount;
        }
        Integer donationCount = donationsDao.selectCount(null);
        AchievementVo achievementVo = new AchievementVo(sum,donationCount,0,0);
        return new ResultVo<>(0,"查询成功",achievementVo);
    }
    //6.已完结，7.异常
    @Override
    public ResultVo<Void> changeStatus(Integer donationsId) {
        Donations donation = donationsDao.getByDonationId(donationsId);
        if(donation.getStatus()==5)
            donation.setStatus(7);
        else donation.setStatus(5);
        int i = donationsDao.updateById(donation);
        if(i==1){
            return new ResultVo<>(0,"操作成功",null);
        }
        return new ResultVo<>(1,"操作失败",null);
    }

    @Override
    public ResultVo<Void> declareEnd(Integer donationsId) {
        Donations donation = donationsDao.getByDonationId(donationsId);
        if(donation.getStatus()==5)
            donation.setStatus(6);
        else donation.setStatus(5);
        int i = donationsDao.updateById(donation);
        if(i==1){
            return new ResultVo<>(0,"操作成功",null);
        }
        return new ResultVo<>(1,"操作失败",null);
    }

    @Override
    public InputStream download(Integer donationId) {
        DonationsInfo donationsInfo = donationsInfoDao.getFileByDonationId(donationId);
        return new ByteArrayInputStream(donationsInfo.getFile());
    }
}
